/**
 * class which represent the Mathematic Expression A+B
 * When A and B are themselfes Mathematical Expressions
 * @author Nadav Cohen, Matan Monitz
 *
 */
public class Addition implements Expression{
	
	private Expression A;
	private Expression B;  // A - left Expression , B - right Expression
	

	
/**
 * 	Constructor Method -
 * create a new Addition object with exp1 parameter as the left expression (A), and exp2 parameter as the right expression (B)
 * copy pointers of Expressions exp1 & exp2, doesnt create new Expressions.
 * incase one of given parameters not iniialzed - points to null - method throw runtime exception
 * @param exp1 - object represent Mathematic Expression which implements Expression
 * @param exp2 - object represent Mathematic Expression which implements Expression 
 */	
	public Addition (Expression exp1, Expression exp2){
		if(exp1==null || exp2==null)
			throw new RuntimeException("Addition couldn't iniliazed - Variable given uninitialzed!");
		A=exp1;
		B=exp2;
	}
	public double evaluate(Assignments assignments) {
		if(assignments==null)   // incase parameter given points to nowhere, throw exception
			throw new RuntimeException("Addition evalutation didnt succeed - Assignments given uninitialzed!");
		return A.evaluate(assignments)+B.evaluate(assignments); // return value of exp. A + value of exp. B 
	}


	public Expression derivative(Variable var) {
		if(var==null) 	// incase parameter given points to nowhere, throw exception (doesnt know by which variable to derive)
			throw new RuntimeException("Addition Derivative didnt succeed - Variable given uninitialzed!");
		Expression derive=null;
			derive= new Addition(A.derivative(var),B.derivative(var));  //addition derive = A` + B`
		return derive;
	}

/**
* compare parameter Object other to this Addition. Objects Equals if:
* - parameter other is type Addition and not null
* - parameter other A Expression is the same A Expression as this object. (left expressions are the same)
* - parameter other B Expression is the same B Expression as this object. (right expressions are the same)
*  @return true if equals, else return false.
*/	
	public boolean equals(Object other){
		boolean ans=false;
		if(other instanceof Addition)
			ans = ( ((Addition)other).A.equals(this.A) && ((Addition)other).B.equals(this.B) );
		return ans;	
	}
	
	public String toString(){
		return "(" + A.toString() + "+" + B.toString() + ")";
	}
}